#include <n32l40x_usart.h>
#include <n32l40x_gpio.h>
#include "usart.h"
#include "gpio.h"
#include "systick.h"
#include "string.h"
usart_cache usart2_cache;
usart_cache usart3_cache;

void usart2_init(void)
{
    /* Enable GPIO clock */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
    /* Enable USART2 Clock */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART2, ENABLE);

    USART_DeInit(USART2);

    NVIC_InitType NVIC_InitStructure;
    /* Configure the NVIC Preemption Priority Bits */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    /* Enable the USART2 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    GPIO_InitType GPIO_InitStructure;
    /* Configure USART2 Tx as alternate function push-pull */
    GPIO_InitStructure.Pin        = GPIO_PIN_4;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF4_USART2;
    GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
    /* Configure USART2 Rx as input floating */
    GPIO_InitStructure.Pin       = GPIO_PIN_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF6_USART2;
    GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);

    USART_InitType USART_InitStructure;
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
    USART_Init(USART2, &USART_InitStructure);

    /* Enable USART2 Receive and Transmit interrupts */
    USART_ConfigInt(USART2, USART_INT_RXDNE, ENABLE);
    USART_ConfigInt(USART2, USART_INT_IDLEF, ENABLE);
//    USART_ConfigInt(USART2, USART_INT_TXDE, ENABLE);

    /* Enable the USART2*/
    USART_Enable(USART2, ENABLE);
    memset(&usart2_cache, 0x00, sizeof(usart2_cache));
}

void usart3_init(void)
{
    /* Enable GPIO clock */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
    /* Enable USART3 Clock */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART3, ENABLE);

    USART_DeInit(USART3);

    NVIC_InitType NVIC_InitStructure;
    /* Configure the NVIC Preemption Priority Bits */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    /* Enable the USART3 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    GPIO_InitType GPIO_InitStructure;
    /* Configure USART3 Tx as alternate function push-pull */
    GPIO_InitStructure.Pin        = GPIO_PIN_10;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF0_USART3;
    GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
    /* Configure USART3 Rx as input floating */
    GPIO_InitStructure.Pin       = GPIO_PIN_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF5_USART3;
    GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);


    USART_InitType USART_InitStructure;
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
    USART_Init(USART3, &USART_InitStructure);

    /* Enable USART3 Receive and Transmit interrupts */
    USART_ConfigInt(USART3, USART_INT_RXDNE, ENABLE);
    USART_ConfigInt(USART3, USART_INT_IDLEF, ENABLE);
//    USART_ConfigInt(USART3, USART_INT_TXDE, ENABLE);

    /* Enable the USART3*/
    USART_Enable(USART3, ENABLE);
    memset(&usart3_cache, 0x00, sizeof(usart3_cache));
}

uint8_t usart_trans(USART_Module* USARTx, uint8_t* Data, uint16_t DataLen)
{
    for(uint32_t i = 0 ; i < DataLen; i++) {
        USART_SendData(USARTx, Data[i]);
        while (USART_GetFlagStatus(USARTx, USART_FLAG_TXDE) == RESET)
        {
        }
    }
    return 0;
}

uint8_t usart_485initial(Type485 Name485)
{
    switch(Name485) {
    case BACKUP_485:
        gpio_init_out(GPIOB, GPIO_PIN_2);
        gpio_off(GPIOB, GPIO_PIN_2);
        break;

    }
    return 0;
}
uint8_t usart_485trans(Type485 Name485, uint8_t* Data, uint16_t DataLen)
{
    switch(Name485) {
    case BACKUP_485:
        gpio_on(GPIOB, GPIO_PIN_2);
        SysTick_Delay_Ms(10);
        usart_trans(USART3, &Data[0], DataLen);
        SysTick_Delay_Ms(10);
        gpio_off(GPIOB, GPIO_PIN_2);
        break;
    }
    return 0;
}

